package yawning.mew.character;

import java.io.FileOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;


public class Talent {
	public static Talent getByName(Clazz clazz, String name) {
		if (sTalentsByName.size() == 0) loadTalents();
		Map<String,Talent> clazzMap = sTalentsByName.get(clazz);
		Talent t = clazzMap.get(name.toLowerCase());
		if (t == null) System.out.println("Talent not found: " + name);
		return t;
	}

	public Clazz getClazz() {
		return mClass;
	}

	public TalentTree getTree() {
		return mTree;
	}

	@Override
	public String toString() {
		return mName;
	}

	public int getId() {
		return mTalentNumber;
	}

	public String getDescription(int rank) {
		return mDescription[rank - 1];
	}

	public int getMaxRank() {
		return mMaxRank;
	}

	private Clazz mClass;
	private TalentTree mTree;
	private String mName;
	private int mTalentNumber;
	private String[] mDescription;
	private int mMaxRank;
	private int tier;
	private int column;

	/**
	 * Function that returns the tier of the talent
	 * @return tier of the talent
	 *
	 * *Added by Ceridan for the TalentPanel to place the talent on the UI.
	 */
	public int getTier(){
		return tier;
	}

	/**
	 * Function that returns the column of the talent
	 * @return column of the talent
	 *
	 * *Added by Ceridan for the TalentPanel to place the talent on the UI.
	 */
	public int getColumn()
	{
		return column;
	}
	public static void main(String args[]) {
		reloadTalents();
		for (Talent t : Clazz.DRUID.getTalents()) System.out.println(t.mTalentNumber + " : " +  t.mName);
	}

	private static final String TALENTS_FILE = "/META-INF/talents.xml";
	private static final String ELEMENT_ROOT = "classes";
	private static final String ELEMENT_CLASS = "class";
	private static final String ELEMENT_TREE = "tree";
	private static final String ATTR_NAME = "name";
	private static final String ATTR_TIER = "tier";
	private static final String ATTR_COLUMN = "column";

	static void loadTalents() {
		synchronized (sTalentsByName) {
			if (sTalentsByName.size() == 0) {
				try {
					SAXBuilder builder = new SAXBuilder();
					Document doc = builder.build(Talent.class.getResourceAsStream(TALENTS_FILE));
					Element root = doc.getRootElement();

					@SuppressWarnings("unchecked") List<Element> classes = root.getChildren(ELEMENT_CLASS);
					for (Element eleClass : classes) {
						Clazz c = Clazz.get(eleClass.getAttributeValue(ATTR_NAME));
						c.mTrees = new ArrayList<TalentTree>();
						c.mTalents = new ArrayList<Talent>();

						@SuppressWarnings("unchecked") List<Element> talentTrees = eleClass.getChildren("tree");
						Element[] ordered = new Element[3];

						// Reorder the elements
						for (Element e : talentTrees) {
							ordered[Integer.parseInt(e.getAttributeValue("order"))] = e;
						}

						int talentId = 0;
						for (Element e : ordered) {
							TalentTree t = new TalentTree();
							t.mClass = c;
							t.mName = e.getAttributeValue(ATTR_NAME);
							c.mTrees.add(t);

							@SuppressWarnings("unchecked") List<Element> tals = e.getChildren("talent");
							for (Element el : tals) {
								Talent tal = new Talent();

								tal.mClass = c;
								tal.mTree = t;
								tal.mName = el.getAttributeValue(ATTR_NAME);
								tal.mTalentNumber = talentId++;
								tal.tier = Integer.parseInt(el.getAttributeValue(ATTR_TIER));
								tal.column = Integer.parseInt(el.getAttributeValue(ATTR_COLUMN));
								@SuppressWarnings("unchecked") List<Element> ranks = el.getChildren("rank");
								tal.mMaxRank = ranks.size();
								tal.mDescription = new String[tal.mMaxRank];
								for (Element rank : ranks) {
									int level = Integer.parseInt(rank.getAttributeValue("lvl"));
									tal.mDescription[level-1] = rank.getAttributeValue("description");
								}

								c.mTalents.add(tal);
								Map<String,Talent> clazzMap = sTalentsByName.get(c);
								if (clazzMap == null) {
									clazzMap = new HashMap<String,Talent>();
									sTalentsByName.put(c, clazzMap);
								}
								clazzMap.put(tal.mName.toLowerCase(), tal);
							}
						}
					}
				}
				catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		}
	}

	private static void reloadTalents() {
		try {
			Element root = new Element(ELEMENT_ROOT);

			for (Clazz c : Clazz.values()) {
				// FIXME: This is going away, rewrite.
				System.out.println("Querying talents for class " + c);
				URL url = new URL("http://www.wowarmory.com/talent-tree.xml?cid=" + c.mCid);
			    SAXBuilder builder = new SAXBuilder();
				Document doc = builder.build(url);
				Element page = doc.getRootElement();

				Element clazz = new Element(ELEMENT_CLASS);
				clazz.setAttribute(ATTR_NAME, c.toString());
				root.addContent(clazz);

				@SuppressWarnings("unchecked") List<Element> talentTrees = page.getChild("talentTrees").getChildren(ELEMENT_TREE);
				Element[] ordered = new Element[3];
				for (Element e : talentTrees) ordered[Integer.parseInt(e.getAttributeValue("order"))] = e;
				for (Element e : ordered) clazz.addContent(e.detach());
			}

			XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
			out.output(new Document(root), new FileOutputStream("talents.xml"));
//			out.output(new Document(root), new FileOutputStream(TALENTS_FILE));
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private static final Map<Clazz,Map<String,Talent>> sTalentsByName = new HashMap<Clazz,Map<String,Talent>>();
//	private static final Map<String,Talent> sTalentsByName = new HashMap<String,Talent>();
}
